using System.Data.SqlClient;
using NUnit.Framework;

namespace DatabaseUnitTesting.Tests
{
    [TestFixture]
    public class DatabaseUnitTesterTests
    {
        private SqlConnection connection;
        private SqlTransaction transaction;
        private string database;
        private string snapshot;
        private string server;
        private DatabaseUnitTester unitTests;

        [TestFixtureSetUp]
        public void TFSetup()
        {
            database = "astyler";
            snapshot = "tempSS";
            server = "(local)";
            string connectionString = "Application Name=UnitTests;Trusted_Connection=true;Server=" + server +
                                      ";Database=" + database;
            connection = new SqlConnection(connectionString);
            connection.Open();
            unitTests = new DatabaseUnitTester(connection, database, snapshot);
        }

        [TestFixtureTearDown]
        public void TFTearDown()
        {
            unitTests.Dispose();
            connection.Close();
        }

        [SetUp]
        public void SetUp()
        {
            transaction = unitTests.BeginTestTransaction();
        }

        [TearDown]
        public void TearDown()
        {
            unitTests.EndTestTransaction();
        }

        [Test]
        public void XmlWritingNoneTest()
        {
            unitTests.AddObjectComparison("dbo", "t100k");
            unitTests.AddColumnToIgnore("dbo", "t100k", "price");

            unitTests.WriteDiffsToXml("C:/Temp/XmlWritingNoneTest.xml");
            Assert.IsTrue(unitTests.CompareDiffsToXml("C:/Temp/XmlWritingNoneTest.xml"));
        }

        [Test]
        public void ThreeUpdatesTest()
        {
            unitTests.AddObjectComparison("dbo", "t100k");
            unitTests.AddColumnToIgnore("dbo", "t100k", "price");

            string commandText = "INSERT INTO t100k (id, c, price) values (-1, 'Unit Test Insert', 99)";
            SqlCommand command = new SqlCommand(commandText, connection);
            command.Transaction = transaction;
            command.ExecuteNonQuery();

            commandText = "UPDATE t100k SET c = 'Unit Test Update' where id = 1";
            command = new SqlCommand(commandText, connection);
            command.Transaction = transaction;
            command.ExecuteNonQuery();

            commandText = "DELETE FROM t100k where id = 40";
            command = new SqlCommand(commandText, connection);
            command.Transaction = transaction;
            command.ExecuteNonQuery();

            unitTests.WriteDiffsToXml("C:/Temp/ThreeUpdatesTest.xml");
            Assert.IsTrue(unitTests.CompareDiffsToXml("C:/Temp/ThreeUpdatesTest.xml"));
        }

        [Test]
        public void ComparisonTest()
        {
            unitTests.AddObjectComparison("dbo", "t100k");

            string commandText = "INSERT INTO t100k (id, c, price) values (-1, 'Unit Test Insert', 99)";
            SqlCommand command = new SqlCommand(commandText, connection);
            command.Transaction = transaction;
            command.ExecuteNonQuery();

            commandText = "UPDATE t100k SET c = 'Unit Test Update' where id = 33";
            command = new SqlCommand(commandText, connection);
            command.Transaction = transaction;
            command.ExecuteNonQuery();

            unitTests.AddColumnToIgnore("dbo", "t100k", "price");

            unitTests.WriteDiffsToXml("C:/Temp/ComparisonTest.xml");
            Assert.IsTrue(unitTests.CompareDiffsToXml("C:/Temp/ComparisonTest.xml"));
        }

        [Test]
        public void IgnoreAllFieldsTest()
        {
            unitTests.AddObjectComparison("dbo", "t100k");
            unitTests.AddColumnToIgnore("dbo", "t100k", "c");
            unitTests.AddColumnToIgnore("dbo", "t100k", "price");

            string commandText = "UPDATE t100k SET c = 'Unit Test Update' where id = 33";
            SqlCommand command = new SqlCommand(commandText, connection);
            command.Transaction = transaction;
            command.ExecuteNonQuery();

            Assert.IsTrue(unitTests.CompareDiffsToXml("xmlFiles/noDiff.xml"));
        }

        [Test]
        public void ReadAndWriteANullTest()
        {
            unitTests.AddObjectComparison("dbo", "t100k");

            string commandText = "UPDATE t100k SET c = NULL where id = 11";
            SqlCommand command = new SqlCommand(commandText, connection);
            command.Transaction = transaction;
            command.ExecuteNonQuery();

            unitTests.WriteDiffsToXml("C:/Temp/NullTest.xml");
            Assert.IsTrue(unitTests.CompareDiffsToXml("C:/Temp/NullTest.xml"));
        }
    }
}